<?php
/**
 * This file is part of the UXLabs project.
 *
 * (c) UXLabs project <http://code.uxlabs.me>
 *
 */

namespace uxl\app\api\controllers;

use uxl\app\api\components\ResultStatus;
use uxl\app\api\models\AccessToken;
use uxl\app\api\models\AppToken;
use Yii;
use uxl\app\api\Bootstrap;

/**
 * 授权处理
 * @package uxl\app\api\controllers
 * @author ice deng <ice.deng@qq.com>
 */
class TokenController extends BaseController
{
    /**
     * @var int 默认有效期为长期有效
     */
    protected $accessKeyExpiresIn = -1;
    /**
     * @var string 有效期在配置params中的key
     */
    protected $accessTokenExpiresInParamsKey = 'appApiAccessTokenExpiresIn';
    /**
     * @var array|null
     */
    protected $appToken;

    /**
     * 获取请求类型
     * @return string
     */
    protected function getRequestType()
    {
        return static::REQUEST_TYPE_AUTH;
    }

    /**
     * 校验accessKey并设置变量$secretKey的值
     * @return bool
     */
    protected function checkAccessKey()
    {
        /** @var AppToken $model */
        $model = Yii::$container->get(AppToken::className());
        $this->appToken = $model->getByAccessKey($this->parameters->accessKey);
        if($this->appToken == false) {
            $errorMsg = 'access key不存在.';
            $this->setErrorResponse(ResultStatus::ACCESS_KEY_ERROR, $errorMsg);
            $this->errorLog($errorMsg);
            return false;
        }
        if($this->appToken['status'] != 1) {
            $errorMsg = 'access key无效.';
            $this->setErrorResponse(ResultStatus::ACCESS_KEY_ERROR, $errorMsg);
            $this->errorLog($errorMsg);
            return false;
        }
        $this->secretKey = $this->appToken['secretKey'];
        return true;
    }

    /**
     * 生成key
     * @return string
     */
    protected function generateKey()
    {
        if (function_exists('com_create_guid') === true) {
            return md5(com_create_guid());
        }
        if (function_exists('uniqid') === true) {
            return md5(uniqid(mt_rand(), true));
        }
        return md5(sprintf('%04X%04X-%04X-%04X-%04X-%04X%04X%04X',
            mt_rand(0, 65535),
            mt_rand(0, 65535),
            mt_rand(0, 65535),
            mt_rand(16384, 20479),
            mt_rand(32768, 49151),
            mt_rand(0, 65535),
            mt_rand(0, 65535),
            mt_rand(0, 65535)));
    }

    /**
     * 获取访问密钥的有效期
     * @return int|string
     */
    protected function getAccessKeyExpiresIn()
    {
        if ($this->accessKeyExpiresIn > -1) {
            return $this->accessKeyExpiresIn;
        }
        if (isset(Yii::$app->params[$this->accessTokenExpiresInParamsKey])) {
            return Yii::$app->params[$this->accessTokenExpiresInParamsKey];
        }
        if (Bootstrap::$accessKeyExpiresIn > -1) {
            return Bootstrap::$accessKeyExpiresIn;
        }
        return 0;
    }

    /**
     * 访问授权
     * @return \uxl\app\api\components\ResultResponse
     */
    public function actionAccess()
    {
        $accessKey = $this->generateKey();
        $secretKey = $this->generateKey();
        $expiresIn = $this->getAccessKeyExpiresIn();
        $clientType = '';
        $clientInfo = '';
        // 获取业务数据
        $data = $this->parameters->getDataValue();
        if ($data && isset($data['client_type'])) {
            $clientType = $data['client_type'];
        }
        if ($data && isset($data['client_info'])) {
            $clientInfo = $data['client_info'];
        }
        /** @var AccessToken $model */
        $model = Yii::$container->get(AccessToken::className());
        if ($model->appendKey($this->appToken['id'], $accessKey, $secretKey, $expiresIn, $clientType, $clientInfo)) {
            return $this->setResultResponse([
                'access_key' => $accessKey,
                'secret_key' => $secretKey,
                'expires_in' => $expiresIn,
            ]);
        } else {
            $this->errorLog("数据库异常, 保存授权信息异常, access_token: $accessKey, secret_token: $secretKey, expires_in: $expiresIn");
            return $this->setErrorResponse(ResultStatus::DATABASE_ERROR, '保存数据异常.');
        }
    }
}